home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
parallax
/
more_exa.tar
/
more
/
Vision
/
random.p
< prev
next >
Wrap
Text File
|
1991-11-18
|
17KB
|
563 lines
SYSTEM Evaluation_of_Random_Stereo_Images ; (* Version 1.0 *)
(* Using the method which is described in an article about LISP: *)
(* Compute the number of hits in a rectangle. The plain with the *)
(* most hits for a certain Pixel get the preference *)
TYPE
string = ARRAY [ 200 ] OF CHAR ;
CONST
maxWidth = 128 ; (* maximal width of input image *)
maxHeigth = 128 ; (* maximal heigth of input image *)
maxDepth = 4 ; (* depth of computation *)
CONFIGURATION
pict [ 1 .. maxHeigth ] , [ 1 .. maxWidth ] ;
CONNECTION
left_port : pict [ i,j ] <-> pict [ i ,j-1 ].right_port ;
up_port : pict [ i,j ] <-> pict [ i-1,j ].down_port ;
SCALAR
LeftPicture ,
RightPicture : ARRAY [ 1 .. maxHeigth ], [ 1 .. maxWidth ] OF INTEGER ;
(* Memory for left and right image *)
Picture : ARRAY [ 1 .. maxHeigth ] , [ 1 .. maxWidth ] OF CHAR ;
i , j , (* counter *)
ToleranceLimit, (* decides if a Pixel belongs to current plane *)
Shifts, (* for calculating sum *)
PicHeigth, (* heigth of input image *)
PicWidth : INTEGER ; (* width of input image *)
Answer, (* for input from console *)
Inputfile,
FileName : string ; (* name of Inputfile *)
Batch : BOOLEAN ; (* flag for Batchmode *)
VECTOR
Pixel : ARRAY [ 1 .. maxDepth ] OF INTEGER ;
(* memory for each image plane *)
Left, (* Pixel of left image *)
Right : INTEGER ; (* Pixel of right image *)
pic : CHAR ;
(************************* STRCAT *******************************************)
(* catenation of two strings *)
PROCEDURE strcat( SCALAR first , second : string ) : SCALAR string ;
SCALAR
i , j : INTEGER ;
BEGIN
i := 0 ; j := 0 ;
WHILE first[i] <> CHR(0) DO INC(i) ; END ;
WHILE second[j] <> CHR(0) DO
first[i] := second[j] ;
INC(j) ; INC(i) ;
END ;
first[i] := CHR(0) ;
RETURN first ;
END strcat ;
(************************** READPICTURE *************************************)
(* reading random image *)
PROCEDURE ReadPicture() : SCALAR BOOLEAN ;
VECTOR
tmp : INTEGER;
SCALAR
Character : CHAR ;
Heigth, Width : INTEGER ;
XPos, YPos : INTEGER ;
DeltaX, DeltaY : INTEGER ;
XIndex, YIndex : INTEGER ;
magic : string ;
color : INTEGER ;
BEGIN
PicHeigth := maxHeigth ;
PicWidth := maxWidth ;
IF NOT Batch THEN
WriteString( "Inputfile (without extension '.l.ppm' and '.r.ppm') : " ) ;
(* requesting Filename *)
ReadString( Inputfile ) ;
ELSE
Inputfile := "batch" ;
END ; (* IF *)
FileName := strcat( Inputfile , ".l.ppm" ) ;
OpenInput( FileName ) ; (* open File *)
IF Done THEN
ReadString( magic ) ;
ReadInt( Width ) ; (* reading Heigth and Width of image *)
ReadInt( Heigth ) ;
CloseInput ;
IF Heigth < PicHeigth THEN
PicHeigth := Heigth ;
END ; (* IF *)
IF Width < PicWidth THEN
PicWidth := Width ;
END ; (* IF *)
IF (Heigth > PicHeigth) OR ( Width > PicWidth ) THEN
IF Batch THEN
DeltaX := -5 ;
ELSE
WriteString( "Image too large. Please enter Image-region : " ) ;
ReadInt( DeltaX ) ;
END ;
IF DeltaX >= 0 THEN
WriteString( "Y-Relocation : " ) ;
ReadInt( DeltaY ) ;
DeltaY := ABS( DeltaY ) ;
IF (Width - PicWidth) < DeltaX THEN
DeltaX := Width - PicWidth ;
END ;
IF (Heigth - PicHeigth) < DeltaY THEN
DeltaY := Heigth - PicHeigth ;
END ;
ELSE (* Delta negativ : using default region *)
CASE ABS( DeltaX ) OF
1 : DeltaX := 0 ; DeltaY := Heigth - PicHeigth ; |
2 : DeltaX := (Width - PicWidth ) DIV 2 ; DeltaY := Heigth - PicHeigth ; |
3 : DeltaX := Width - PicWidth ; DeltaY := Heigth - PicHeigth ; |
4 : DeltaX := 0 ; DeltaY := (Heigth - PicHeigth) DIV 2 ; |
5 : DeltaX := (Width - PicWidth ) DIV 2 ; DeltaY := (Heigth - PicHeigth) DIV 2 ; |
6 : DeltaX := Width - PicWidth ; DeltaY := (Heigth - PicHeigth) DIV 2 ; |
7 : DeltaX := 0 ; DeltaY := 0 ; |
8 : DeltaX := (Width - PicWidth ) DIV 2 ; DeltaY := 0 ; |
9 : DeltaX := Width - PicWidth ; DeltaY := 0 ;
ELSE
WriteString("Incorrect region.") ; WriteLn ;
RETURN FALSE ;
END ; (* CASE ABS(DeltaX) *)
END ; (* IF DeltaX >= 0 *)
ELSE
DeltaX := 0 ; DeltaY := 0 ;
END ; (* IF (Heigth.. *)
PARALLEL
tmp := 0;
ENDPARALLEL;
STORE (tmp, LeftPicture);
STORE (tmp, RightPicture);
OpenInput( FileName ) ;
ReadString( magic ) ;
ReadInt( Width ) ; Read( Character ) ; (* read Linefeed *)
ReadInt( Heigth ) ; Read( Character ) ; (* read Linefeed *)
ReadInt( color ); Read( Character ) ;
WriteString( "Reading left image ..." ) ;
WriteLn ;
XIndex := 1;
YIndex := 1;
FOR YPos := 1 TO Heigth DO
FOR XPos := 1 TO Width DO
Read( Character ) ;
Read( Character ) ;
Read( Character ) ;
IF (DeltaY < YPos <= (DeltaY+PicHeigth)) AND (* check image region *)
(DeltaX < XPos <= (DeltaX+PicWidth)) THEN
LeftPicture[YPos - DeltaY][XPos - DeltaX] := ORD( Character ) ;
END ; (* IF *)
END ; (* FOR *)
END ; (* FOR *)
FileName := strcat( Inputfile , ".r.ppm" ) ;
OpenInput( FileName ) ;
ReadString( magic ) ;
ReadInt( Width ) ; Read( Character ) ; (* read Linefeed *)
ReadInt( Heigth ) ; Read( Character ) ; (* read Linefeed *)
ReadInt( color ); Read( Character ) ;
WriteString( "Reading right image ..." ) ;
WriteLn ;
FOR YPos := 1 TO Heigth DO
FOR XPos := 1 TO Width DO
Read( Character ) ;
Read( Character ) ;
Read( Character ) ;
IF (DeltaY < YPos <= (DeltaY+PicHeigth)) AND (* check image region *)
(DeltaX < XPos <= (DeltaX+PicWidth)) THEN
IF ( XIndex = maxWidth ) THEN
XIndex := 0; INC( YIndex );
ELSE
INC( XIndex );
END;
RightPicture[ YPos - DeltaY ][ XPos - DeltaX ] := ORD( Character ) ;
END ; (* IF *)
END ; (* FOR *)
END ; (* FOR *)
RETURN TRUE ;
ELSE
WriteString( "File not found." ) ; WriteLn ;
RETURN FALSE ;
END ;(* IF Done *)
END ReadPicture ;
(************************** PARALLELSUM *************************************)
(* This function counts how many marked Pixel (value = '1') surrounds the *)
(* Pixel, which is in the center of a square with edge length 2*Shifts+1. *)
(* Shifts is a global variable for setting square size *)
PROCEDURE Parallelsum( VECTOR my_number : INTEGER ) : VECTOR INTEGER ;
SCALAR
i : INTEGER ; (* counter *)
VECTOR
sum, (* quantity of marked Pixel surrounding a Pixel *)
shift_number1,
shift_number2 : INTEGER ; (* number which is sending to the neighbour *)
BEGIN
sum := my_number ; (* number of myself *)
shift_number1 := my_number ;
shift_number2 := my_number ;
FOR i := 1 TO Shifts DO
PROPAGATE .right_port( shift_number1 ) ;
(* sending pixelvalue to the right *)
PROPAGATE .left_port( shift_number2 ) ;
(* sending pixelvalue to the left *)
sum := sum + shift_number1 + shift_number2 ;
END ;
my_number := sum ; (* store of calculated horizontal sum *)
shift_number1 := my_number ; (* and sending above and below *)
shift_number2 := my_number ;
FOR i := 1 TO Shifts DO
PROPAGATE .up_port( shift_number1 ) ; (* sending above *)
PROPAGATE .down_port( shift_number2 ) ; (* sending below *)
sum := sum + shift_number1 + shift_number2 ;
END ;
RETURN sum ; (* sum contains now the sum of marked *)
(* Pixel (value = '1') in the square *)
END Parallelsum ;
(************************** Show_Plains *************************************)
(* This procedure display the results of each image-plain for possible *)
(* viewing after each calculating step *)
PROCEDURE Show_Plains ;
SCALAR
plain, x, y : INTEGER ;
BEGIN
IF NOT Batch THEN
REPEAT
WriteString( "Which plain do you want to see ? ( 1 .. ");
WriteInt( maxDepth , 1 ) ;
WriteString(" , 0 = no plain ) : ") ;
ReadInt( plain ) ;
IF 1 <= plain <= maxDepth THEN
PARALLEL
pic := CHR(0);
ENDPARALLEL;
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
pic := CHR(Pixel[ plain ]+ORD('0'));
ENDPARALLEL ;
STORE( pic , Picture ) ;
WriteString("Image Plain : ") ; WriteInt( plain , 1 ) ; WriteLn ;
FOR y := 1 TO PicHeigth DO
WriteString( Picture[y] ) ;
WriteLn ;
END ; (* FOR y *)
WriteLn ;
END ; (* IF 1 <= plain .. *)
UNTIL plain = 0 ;
END ; (* IF NOT Batch *)
END Show_Plains ;
(************************** Show_All ****************************************)
(* This procedure display the results of all image plains *)
PROCEDURE Show_All ;
SCALAR
plain,
x, y : INTEGER ;
VECTOR
Heigth : INTEGER ;
BEGIN
PARALLEL
pic := CHR (0);
ENDPARALLEL;
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
FOR plain := 1 TO maxDepth DO (* to which plain belongs a plain *)
IF Pixel[ plain ] = 1 THEN
Heigth := plain ;
END ; (* IF Pixel[plain] = 1 *)
END ; (* FOR *)
pic := CHR(Heigth+ORD('0')-1);
ENDPARALLEL ;
IF NOT Batch THEN
STORE( pic , Picture ) ;
FOR y := 1 TO PicHeigth DO
WriteString( Picture[y] ) ;
WriteLn ;
END ; (* FOR y *)
WriteLn ;
END ; (* IF NOT Batch *)
END Show_All ;
(************************** Common_Elements *********************************)
(* The vectors Left and Right contains in the beginning both images in the *)
(* right position against one another. If both pixel have the same value, *)
(* then it would be marked by storing 1 in Pixel[ plain ]. Afterwards the *)
(* left image would be shifted left by one pixel and searched again for *)
(* common elements with the right image. This repeats until maxDepht is *)
(* reached *)
PROCEDURE Common_Elements ;
SCALAR
plain : INTEGER ;
BEGIN
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
FOR plain := 1 TO maxDepth DO (* for each image plain *)
Pixel[plain] := 0 ; (* different Pixel *)
IF Left = Right THEN
Pixel[plain] := 1 ; (* equal Pixel *)
END ;
PROPAGATE .left_port(Left) ; (* shifting left image one position to the left *)
END ;
ENDPARALLEL ;
END Common_Elements ;
(************************** Search_Objects **********************************)
(* For almost each pixel it exists some possible plains. By comparing with *)
(* neighbour-pixels it can be find out to which plain a pixel belongs. *)
PROCEDURE Search_Objects ;
SCALAR
plain : INTEGER ;
VECTOR
max,
maxpos,
Pixelsum : INTEGER ;
BEGIN
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
max := 0 ; maxpos := 1 ;
FOR plain := 1 TO maxDepth DO (* for each image plain *)
Pixelsum := Parallelsum( Pixel[plain] ) ;
(* calculating sum of surrounding p *)
IF (Pixel[ plain ] = 1) AND (Pixelsum > max) THEN
(* if new maximum found *)
maxpos := plain ; (* store current plain *)
max := Pixelsum ; (* store maximum *)
END ; (* IF Pixelsum *)
Pixel[ plain ] := 0 ; (* delete plain *)
END ; (* FOR plain *)
Pixel[ maxpos ] := 1 ; (* mark found plain with 1 *)
ENDPARALLEL ;
END Search_Objects ;
(************************** FILTER ******************************************)
(* It's possible, that some few pixel would not be correct calculated. *)
(* The procedure Filter has to search for these pixels and then assign *)
(* to a suitable plain. *)
PROCEDURE Filter ;
SCALAR
plain : INTEGER ;
VECTOR
max,
maxpos,
Pixelsum : INTEGER ;
change : BOOLEAN ;
BEGIN
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
max := 0 ; change := FALSE ;
FOR plain := 1 TO maxDepth DO (* for each image plain *)
Pixelsum := Parallelsum( Pixel[plain] ) ; (* look at neighbourhood *)
IF Pixelsum > max THEN
max := Pixelsum ; (* store the propably best plain *)
maxpos := plain ;
END ; (* IF Pixelsum *)
IF ( Pixel[plain] = 1 ) AND ( Pixelsum <= ToleranceLimit ) THEN
(* 'lost pixel' ?? *)
Pixel[plain] := 0 ;
change := TRUE ;
END ; (* IF Pixel[ plain ] *)
END ; (* FOR plain *)
IF change THEN
Pixel[maxpos] := 1 ; (* 'lost pixel' get a new plain *)
END ; (* IF change *)
ENDPARALLEL ;
END Filter ;
(************************* PPM_Output **************************************)
(* saving the resulting image, File Format is PPM *)
PROCEDURE PPM_Output ;
SCALAR
i, j, plain : INTEGER ;
VECTOR
Heigth : INTEGER ;
BEGIN
PARALLEL
Heigth := 0;
ENDPARALLEL;
PARALLEL [ 1 .. PicHeigth ] , [ 1 .. PicWidth ]
FOR plain := 1 TO maxDepth DO (* to which plain belongs a pixel *)
IF Pixel[ plain ] = 1 THEN
Heigth := plain ;
END ; (* IF Pixel[plain] = 1 *)
END ; (* FOR *)
pic := CHR( Heigth+ORD('0')-1 );
ENDPARALLEL ;
STORE( Heigth , LeftPicture ) ;
OpenOutput( FileName ) ;
WriteString( "P6" ) ; WriteLn ; (* RAWBIT option, not ASCII *)
WriteInt( PicWidth, 1 ) ; WriteLn ;
WriteInt( PicHeigth, 1 ) ; WriteLn ;
WriteInt( maxDepth, 1 ) ; WriteLn ; (* maximum color-component value *)
FOR i := 1 TO PicHeigth DO
FOR j := 1 TO PicWidth DO (* saving pixel: *)
Write( CHR( LeftPicture[i,j] )) ; (* red value *)
Write( CHR( LeftPicture[i,j] )) ; (* green value *)
Write( CHR( LeftPicture[i,j] )) ; (* blue value *)
END ; (* FOR j *)
END ; (* FOR i *)
CloseOutput ;
END PPM_Output ;
(************************** Main Program ************************************)
SCALAR
c : CHAR;
BEGIN
OpenInput( "Batch" ) ;
IF Done THEN
Batch := TRUE ; WriteString( "Program in Batch-Mode ..." ) ; WriteLn ;
ELSE
Batch := FALSE ;
END ;
CloseInput ;
IF ReadPicture() = FALSE THEN
WriteString("###### Program terminated abnormaly ######" ) ;
WriteLn ; HALT ;
END ;
CloseInput ; (* return to input from console *)
(* explore both images : *)
(* first both images would be put one upon the other und extract common *)
(* elements. Then one image would be shifted and compared again with the *)
(* other and so on. *)
LOAD( Left , LeftPicture ) ;
LOAD( Right , RightPicture ) ;
WriteString( "Examine left an right image for common elements ...") ;
WriteLn ;
Common_Elements ;
Show_Plains ;
WriteString("Discovering objects in each plain ...") ; WriteLn ;
Shifts := 2 ; (* Neighbourhood with 5x5 = 25 Pixel *)
Search_Objects ; (* find for each pixel the right plain *)
Show_Plains ;
Show_All ;
Shifts := 1 ; (* Neighbourhood with 3x3 = 9 Pixel *)
ToleranceLimit := 4 ;
WriteString("Filter ...") ; WriteLn ;
IF NOT Batch THEN
REPEAT
Filter ;
Show_Plains ;
Show_All ;
WriteString("Filter again (y/n) ? ") ; ReadString( Answer ) ;
UNTIL Answer[0] <> 'y' ;
ELSE
Filter ;
Filter ;
Show_All ;
END ; (* IF NOT Batch *)
FileName := strcat( Inputfile , ".out.ppm" ) ;
WriteString( "Saving resulting image as '") ;
WriteString( FileName ) ;
WriteString( "' ..." ) ; WriteLn ;
PPM_Output;
CloseInput ;
END Evaluation_of_Random_Stereo_Images.